#include "qtvtkmainwindow.h"

// Constructor
QtVTKMainWindow::QtVTKMainWindow(QWidget *parent, Qt::WFlags flags)
	: QMainWindow(parent, flags)
{
	// Set up ui
	ui.setupUi(this);

	// Initialize osimManager
	osimManager = osimMethods::osimSimulation();

	// Initialize vtkSceneManager
	vtkSceneManager = vtkMethods::vtkScene();

	// Add renderWindow to qvtkWidget 
	ui.qvtkWidget->GetRenderWindow()->AddRenderer(vtkSceneManager.renderer);

	// Render
	ui.qvtkWidget->GetRenderWindow()->Render();
}

// Destructor
QtVTKMainWindow::~QtVTKMainWindow()
{

}

// File Menu

void QtVTKMainWindow::on_actionBlank_Model_activated(void)
{
	// Enable menus
	ui.menuModel->setEnabled(true);
	ui.menuAdd->setEnabled(true);
	ui.menuAnalysis->setEnabled(true);

	// Enable list items
	ui.treeWidget->findItems("New Model",Qt::MatchExactly,0).first()->setDisabled(false);
	ui.treeWidget->findItems("Bodies",Qt::MatchExactly | Qt::MatchRecursive,0).first()->setDisabled(false);
	ui.treeWidget->findItems("Joints",Qt::MatchExactly | Qt::MatchRecursive,0).first()->setDisabled(false);
	ui.treeWidget->findItems("Constraints",Qt::MatchExactly | Qt::MatchRecursive,0).first()->setDisabled(false);
	ui.treeWidget->findItems("Contact Geometry",Qt::MatchExactly | Qt::MatchRecursive,0).first()->setDisabled(false);
	ui.treeWidget->findItems("Forces",Qt::MatchExactly | Qt::MatchRecursive,0).first()->setDisabled(false);
	ui.treeWidget->findItems("Markers",Qt::MatchExactly | Qt::MatchRecursive,0).first()->setDisabled(false);

	// Expand top level item
	ui.treeWidget->findItems("New Model",Qt::MatchExactly,0).first()->setExpanded(true);

}

void QtVTKMainWindow::on_actionKnee_Model_activated(void)
{
	// Enable menus
	ui.menuModel->setEnabled(true);
	ui.menuAdd->setEnabled(true);
	ui.menuAnalysis->setEnabled(true);

	// Enable list items
	ui.treeWidget->findItems("New Model",Qt::MatchExactly,0).first()->setDisabled(false);
	ui.treeWidget->findItems("Bodies",Qt::MatchExactly | Qt::MatchRecursive,0).first()->setDisabled(false);
	ui.treeWidget->findItems("Joints",Qt::MatchExactly | Qt::MatchRecursive,0).first()->setDisabled(false);
	ui.treeWidget->findItems("Constraints",Qt::MatchExactly | Qt::MatchRecursive,0).first()->setDisabled(false);
	ui.treeWidget->findItems("Contact Geometry",Qt::MatchExactly | Qt::MatchRecursive,0).first()->setDisabled(false);
	ui.treeWidget->findItems("Forces",Qt::MatchExactly | Qt::MatchRecursive,0).first()->setDisabled(false);
	ui.treeWidget->findItems("Markers",Qt::MatchExactly | Qt::MatchRecursive,0).first()->setDisabled(false);

	// Expand top level item
	ui.treeWidget->findItems("New Model",Qt::MatchExactly,0).first()->setExpanded(true);

	// Create OpenSim model from file
	//osimMethods::osimKneeModel model = osimMethods::osimKneeModel();

}

void QtVTKMainWindow::on_actionOpen_Model_activated(void)
{


	// Open file input dialog
	QString qfileName;
	qfileName = QFileDialog::getOpenFileName(this, tr("Import .osim model file."), "", tr("OpenSim Files (*.osim)"));
	QFileInfo fileInfo(qfileName);

	// Enable menus
	ui.menuModel->setEnabled(true);
	ui.menuAdd->setEnabled(true);
	ui.menuAnalysis->setEnabled(true);

	// Enable list items
	ui.treeWidget->findItems("New Model",Qt::MatchExactly,0).first()->setDisabled(false);
	ui.treeWidget->findItems("Bodies",Qt::MatchExactly | Qt::MatchRecursive,0).first()->setDisabled(false);
	ui.treeWidget->findItems("Joints",Qt::MatchExactly | Qt::MatchRecursive,0).first()->setDisabled(false);
	ui.treeWidget->findItems("Constraints",Qt::MatchExactly | Qt::MatchRecursive,0).first()->setDisabled(false);
	ui.treeWidget->findItems("Contact Geometry",Qt::MatchExactly | Qt::MatchRecursive,0).first()->setDisabled(false);
	ui.treeWidget->findItems("Forces",Qt::MatchExactly | Qt::MatchRecursive,0).first()->setDisabled(false);
	ui.treeWidget->findItems("Markers",Qt::MatchExactly | Qt::MatchRecursive,0).first()->setDisabled(false);

	// Expand top level item
	ui.treeWidget->findItems("New Model",Qt::MatchExactly,0).first()->setExpanded(true);

	// Update StatusBar
	QString message1 = "Importing ";
	message1.append(fileInfo.fileName());
	message1.append("...");
	ui.statusBar->showMessage(message1,5000);

	// Open OpenSim model from file
	osimManager.addModelfromFile(qfileName.toStdString());

	// Get OpenSim model name
	std::string modelName = osimManager.getModelName();

	// Update StatusBar
	QString message2 = "Successfully imported ";
	message2.append(QString(modelName.c_str()));
	ui.statusBar->showMessage(message2,5000);

	// Get tree items
	std::map<int,std::map<int,std::string>> treeitems = osimManager.getTreeItems();

	// Update tree list
	updateTreeList(treeitems);

}

void QtVTKMainWindow::on_actionSave_Model_As_activated(void)
{
	osimManager.osimModels[1].print("model_modified.osim");
}

void QtVTKMainWindow::on_actionQuit_activated(void)
{
	// Close GUI
	close();
}

void QtVTKMainWindow::on_actionBody_activated(void)
{
	qtvtkbodyproperties b(this);
	int isok = b.exec();
	if (isok)
	{
		std::cout << "body added " << std::endl;
	}
}

void QtVTKMainWindow::on_actionJoint_activated(void)
{

}

void QtVTKMainWindow::on_actionConstraint_activated(void)
{

}

void QtVTKMainWindow::on_actionContact_Geometry_activated(void)
{

}
void QtVTKMainWindow::on_actionForce_activated(void)
{

}

void QtVTKMainWindow::on_actionMarker_activated(void)
{

}

void QtVTKMainWindow::on_actionRegistration_activated(void)
{
	qtvtkregistrationutility b(this);
	int isok = b.exec();
}

void QtVTKMainWindow::updateTreeList(std::map<int,std::map<int,std::string>> treeitems)
{
	// Create iterator to treeitems
	std::map<int, std::string>::iterator it;

	// Create a QTreeWidgetItem for each object set and store in QList
	for(it = treeitems[1].begin(); it != treeitems[1].end(); it++){BodiesTreeList.append(QTreeWidgetItem(QStringList(QString(it->second.c_str())),0));}
	for(it = treeitems[2].begin(); it != treeitems[2].end(); it++){JointsTreeList.append(QTreeWidgetItem(QStringList(QString(it->second.c_str())),0));}
	for(it = treeitems[3].begin(); it != treeitems[5].end(); it++){ConstraintsTreeList.append(QTreeWidgetItem(QStringList(QString(it->second.c_str())),0));}
	for(it = treeitems[4].begin(); it != treeitems[5].end(); it++){ContactGeometryTreeList.append(QTreeWidgetItem(QStringList(QString(it->second.c_str())),0));}
	for(it = treeitems[5].begin(); it != treeitems[5].end(); it++){ForcesTreeList.append(QTreeWidgetItem(QStringList(QString(it->second.c_str())),0));}
	for(it = treeitems[6].begin(); it != treeitems[5].end(); it++){MarkersTreeList.append(QTreeWidgetItem(QStringList(QString(it->second.c_str())),0));}

	// Create QList<QTreeWidgetItem*> of pointers to QTreeWidgetItem's
	QList<QTreeWidgetItem*> _BodiesTreeList;
	QList<QTreeWidgetItem*> _JointsTreeList;
	QList<QTreeWidgetItem*> _ConstraintsTreeList;
	QList<QTreeWidgetItem*> _ContactGeometryTreeList;
    QList<QTreeWidgetItem*> _ForcesTreeList;
	QList<QTreeWidgetItem*> _MarkersTreeList;

	// Create an iterator to a QList<QTreeWidgetItem>
	QList<QTreeWidgetItem>::iterator qit;

	// Store pointers for each list object
	for (qit = BodiesTreeList.begin(); qit != BodiesTreeList.end(); ++qit){_BodiesTreeList.push_back(&(*qit));}
	for (qit = JointsTreeList.begin(); qit != JointsTreeList.end(); ++qit){_JointsTreeList.push_back(&(*qit));}
	for (qit = ConstraintsTreeList.begin(); qit != ConstraintsTreeList.end(); ++qit){_ConstraintsTreeList.push_back(&(*qit));}
	for (qit = ContactGeometryTreeList.begin(); qit != ContactGeometryTreeList.end(); ++qit){_ContactGeometryTreeList.push_back(&(*qit));}
	for (qit = ForcesTreeList.begin(); qit != ForcesTreeList.end(); ++qit){_ForcesTreeList.push_back(&(*qit));}
	for (qit = MarkersTreeList.begin(); qit != MarkersTreeList.end(); ++qit){_MarkersTreeList.push_back(&(*qit));}

	// Add all children to top level QTreeWidgetItem's
	ui.treeWidget->findItems("Bodies",Qt::MatchExactly | Qt::MatchRecursive,0).first()->addChildren(_BodiesTreeList);
	ui.treeWidget->findItems("Joints",Qt::MatchExactly | Qt::MatchRecursive,0).first()->addChildren(_JointsTreeList);
    ui.treeWidget->findItems("Constraints",Qt::MatchExactly | Qt::MatchRecursive,0).first()->addChildren(_ConstraintsTreeList);
	ui.treeWidget->findItems("Contact Geometry",Qt::MatchExactly | Qt::MatchRecursive,0).first()->addChildren(_ContactGeometryTreeList);
	ui.treeWidget->findItems("Forces",Qt::MatchExactly | Qt::MatchRecursive,0).first()->addChildren(_ForcesTreeList);
	ui.treeWidget->findItems("Markers",Qt::MatchExactly | Qt::MatchRecursive,0).first()->addChildren(_MarkersTreeList);
}

/*
void QtVTKMainWindow::on_actionImportGeometry_activated(void)
{
	// Defing a QString, std::string, and a vtkActor
	QString qfileName;
	std::string stdfileName;
	vtkSmartPointer<vtkActor> actor;

	// Open file input dialog
	qfileName = QFileDialog::getOpenFileName(this, tr("Import .stl geometry file."), "", tr("STL Files (*.STL *.stl)"));
	QFileInfo fileInfo(qfileName);

	// Convert QString to std::string
	stdfileName = qfileName.toStdString();

	// Import stl geometry into vtk
	actor = vtkMethods::vtkloadstl(stdfileName);

	// Add actor to scene
	vtkSceneManager.AddActor(fileInfo.fileName().toStdString().c_str(), actor);

	// Reset camera
	vtkSceneManager.renderer->ResetCamera()

	// Update StatusBar
	QString message = "Successfully imported ";
	message.append(fileInfo.fileName());
	ui.statusBar->showMessage(message,5000);
}

void QtVTKMainWindow::on_actionImportKinematics_activated(void)
{
	// Defing a QString, std::string, and a vtkTransformCollection
	QString qfileName;
	std::string stdfileName;
	vtkSmartPointer<vtkTransformCollection> transformCollection;

	// Open file input dialog
	qfileName = QFileDialog::getOpenFileName(this, tr("Import .jts kinematics file."), "", tr("JTS Files (*.JTS *.jts)"));
	QFileInfo fileInfo(qfileName);

	// Convert QString to std::string
	stdfileName = qfileName.toStdString();

	// Import kinematics from jts file
	//vtkSceneManager.transformCollection = vtkMethods::vtkImportJTS(stdfileName1);

	// Update StatusBar
	QString message = "Successfully imported ";
	message.append(fileInfo.fileName());
	ui.statusBar->showMessage(message,5000);

}
*/